home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 1
/
Nebula One.iso
/
Mail
/
pine3.92
/
pine
/
osdep
/
sendmail
< prev
next >
Wrap
Text File
|
1996-03-14
|
7KB
|
254 lines
/*----------------------------------------------------------------------
Routines used to hand off messages to local agents for sending/posting
The two exported routines are:
1) smtp_command() -- used to get local transport agent to invoke
2) post_handoff() -- used to pass messages to local posting agent
----*/
/*
* Protos for "sendmail" internal functions
*/
static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
static long pine_pipe_soutr_nl PROTO((void *, char *));
/* ----------------------------------------------------------------------
Figure out command to start local SMTP agent
Args: errbuf -- buffer for reporting errors (assumed non-NULL)
Returns an alloc'd copy of the local SMTP agent invocation or NULL
----*/
char *
smtp_command(errbuf)
char *errbuf;
{
#if defined(SENDMAIL) && defined(SENDMAILFLAGS)
char tmp[256];
sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
return(cpystr(tmp));
#else
strcpy(errbuf, "No default posting command.");
return(NULL);
#endif
}
/*----------------------------------------------------------------------
Hand off given message to local posting agent
Args: envelope -- The envelope for the BCC and debugging
header -- The text of the message header
errbuf -- buffer for reporting errors (assumed non-NULL)
----*/
int
mta_handoff(header, body, errbuf)
METAENV *header;
BODY *body;
char *errbuf;
{
char cmd_buf[256], *cmd = NULL;
/*
* A bit of complicated policy implemented here.
* There are two posting variables sendmail-path and smtp-server.
* Precedence is in that order.
* They can be set one of 4 ways: fixed, command-line, user, or globally.
* Precedence is in that order.
* Said differently, the order goes something like what's below.
*
* NOTE: the fixed/command-line/user precendence handling is also
* indicated by what's pointed to by ps_global->VAR_*, but since
* that also includes the global defaults, it's not sufficient.
*/
if(ps_global->FIX_SENDMAIL_PATH
&& ps_global->FIX_SENDMAIL_PATH[0]){
cmd = ps_global->FIX_SENDMAIL_PATH;
}
else if(!(ps_global->FIX_SMTP_SERVER
&& ps_global->FIX_SMTP_SERVER[0])){
if(ps_global->COM_SENDMAIL_PATH
&& ps_global->COM_SENDMAIL_PATH[0]){
cmd = ps_global->COM_SENDMAIL_PATH;
}
else if(!(ps_global->COM_SMTP_SERVER
&& ps_global->COM_SMTP_SERVER[0])){
if(ps_global->USR_SENDMAIL_PATH
&& ps_global->USR_SENDMAIL_PATH[0]){
cmd = ps_global->USR_SENDMAIL_PATH;
}
else if(!(ps_global->USR_SMTP_SERVER
&& ps_global->USR_SMTP_SERVER[0])){
if(ps_global->GLO_SENDMAIL_PATH
&& ps_global->GLO_SENDMAIL_PATH[0]){
cmd = ps_global->GLO_SENDMAIL_PATH;
}
#ifdef DF_SENDMAIL_PATH
/*
* This defines the default method of posting. So,
* unless we're told otherwise use it...
*/
else if(!(ps_global->GLO_SMTP_SERVER
&& ps_global->GLO_SMTP_SERVER[0])){
strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
}
#endif
}
}
}
*errbuf = '\0';
if(cmd){
dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
(void) mta_parse_post(header, body, cmd, errbuf);
return(1);
}
else
return(0);
}
/*----------------------------------------------------------------------
Hand off given message to local posting agent
Args: envelope -- The envelope for the BCC and debugging
header -- The text of the message header
errbuf -- buffer for reporting errors (assumed non-NULL)
Fork off mailer process and pipe the message into it
Called to post news via Inews when NNTP is unavailable
----*/
char *
post_handoff(header, body, errbuf)
METAENV *header;
BODY *body;
char *errbuf;
{
char *err = NULL;
#ifdef SENDNEWS
char *s;
if(s = strstr(header->env->date," (")) /* fix the date format for news */
*s = '\0';
if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
if(s)
*s = ' '; /* restore the date */
#else /* !SENDNEWS */ /* this is the default case */
sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
#endif /* !SENDNEWS */
return(err);
}
/*----------------------------------------------------------------------
Hand off message to local MTA; it parses recipients from 822 header
Args: header -- struct containing header data
body -- struct containing message body data
cmd -- command to use for handoff (%s says where file should go)
errs -- pointer to buf to hold errors
----*/
static char *
mta_parse_post(header, body, cmd, errs)
METAENV *header;
BODY *body;
char *cmd;
char *errs;
{
char c, *p, *result = NULL;
int rv;
PIPE_S *pipe;
dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
/* tie off cmd */
for(p = cmd; (c = *p) && !isspace(*p); p++)
;
*p = *errs = '\0';
rv = can_access(cmd, EXECUTE_ACCESS);
*p = c;
if(!rv){
if(pipe = open_system_pipe(cmd, &result, NULL,
PIPE_STDERR | PIPE_WRITE | PIPE_PROT | PIPE_NOSHELL)){
if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
(TCPSTREAM *) pipe))
strcpy(errs, "Error posting.");
if(close_system_pipe(&pipe) && !*errs){
sprintf(errs, "Posting program %s returned error", cmd);
if(result)
display_output_file(result, "POSTING ERRORS", errs);
}
}
else
sprintf(errs, "Error running cmd: %s", cmd);
if(result){
unlink(result);
fs_give((void **)&result);
}
}
else
sprintf(errs, "Error with \"%s\" : %s", cmd,
(errno > 0) ? error_description(errno) : "not executable");
return(*errs ? errs : NULL);
}
/*
* pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
* pipes rather than a tcp stream
*/
static long
pine_pipe_soutr_nl (stream,s)
void *stream;
char *s;
{
long rv = T;
char *p;
size_t n;
while(*s && rv){
/* map CR LF ? */
if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
do
rv = fwrite(s, n, (size_t) 1, ((PIPE_S *)stream)->ofilep);
while(!rv && ferror(((PIPE_S *)stream)->ofilep) && errno == EINTR);
if(p && rv){
s = p + 2;
do /* write UNIX EOL */
rv = fwrite("\n", (size_t)1, (size_t)1,
((PIPE_S *)stream)->ofilep);
while(!rv && ferror(((PIPE_S *)stream)->ofilep)
&& errno == EINTR);
}
else
break;
}
return(rv);
}